%-----------------> REWRITE METHOD BODIES
change_methodbodycount(BC, NewBC) :-
	NewBC is BC.

change_methodbodyinfo(MBs, MarkedList, CP, NewMBs, NewMarkedList) :-

	empty_assoc(OTN),
	empty_assoc(NTO),
	b_setval(oldtonew,OTN),
	b_setval(newtoold,NTO),

	empty_assoc(MKD),
	b_setval(markedinstr,MKD),

		
	add_sec_var_instructions(MBs,CP,MarkedList,TempMBs,TempMarkedList),

	fix_them_branches(TempMBs, NewMBs),
	
	fix_them_marks(NewMBs, TempMarkedList, NewMarkedList).

%correct_marked_lists(JumpTable,NewMBs,TempMarkedList,NewMarkedList).

fix_them_marks([], [], []).
fix_them_marks([MB|MBs], [(Method-Marks)|Rest], [(Method-NewMarks)|NewRest]) :-
	MB =.. [method_body, Method, _MS, _LC, _ISD, _MSD, _CL, C, _EC, _E, _TC, _T],
	fix_that_there_marking(C, Marks, NewMarks),
	fix_them_marks(MBs, Rest, NewRest).

fix_that_there_marking([], [], []).
fix_that_there_marking([I|Is], [Mark|Marks], [(I,Mark)|NewMarks]) :-
	fix_that_there_marking(Is, Marks, NewMarks).

fix_them_branches([],[]).
fix_them_branches([TMB|TM], [NMB|NM]) :-

	TMB =.. [method_body, MethodNum, MS, LC, ISD, MSD, CL, C, EC, E, TC, T],

	fix_that_there_method(MethodNum, C, NewC),

	NMB =.. [method_body, MethodNum, MS, LC, ISD, MSD, CL, NewC, EC, E, TC, T],

	fix_them_branches(TM, NM).

% Base Case
fix_that_there_method(_,[],[]).

% Not a Branch Case
fix_that_there_method( MN, [(Offset-H)|TRest], [(Offset-H)|NRest]) :-
	H =.. [Head | _Args],
	\+isABranch(Head),
	fix_that_there_method(MN, TRest, NRest).

% LookUpSwitch Case
fix_that_there_method(MN, [(Offset-H)|TRest], [(Offset-NewH)|NRest]) :-
	H =.. [lookupswitch, DefaultOffset, CaseCount, CaseOffsets],

	%	spy(get_assoc),

	
	%	write('LUS: '), writeln((Offset-H)), 

	b_getval(markedinstr, MKD),

	((get_assoc((MN-Offset), MKD, _VAL)) ->
		NewH =.. [lookupswitch, DefaultOffset, CaseCount, CaseOffsets],
		fix_that_there_method(MN, TRest, NRest)
	;
		b_getval(oldtonew, OTN),
		b_getval(newtoold, NTO),

		% Get the Original Offset
		get_assoc((MN-Offset), NTO, (MN-OldOffset)),
		OldDefaultTarget is (OldOffset+DefaultOffset),
		get_assoc((MN-OldDefaultTarget), OTN, (MN-NewDefaultTarget)),
		NewDefaultOffset is (NewDefaultTarget-Offset),

		fix_case_offsets(MN, Offset, OldOffset, CaseOffsets, NewCaseOffsets),

		writeln(CaseOffsets),
		writeln(NewCaseOffsets),

		NewH =.. [lookupswitch, NewDefaultOffset, CaseCount, NewCaseOffsets],
		fix_that_there_method(MN, TRest, NRest)
	).

% Branch or Jump Case
fix_that_there_method(MN, [(Offset-H)|TRest], [(Offset-NewH)|NRest]) :-
	H =.. [Head | Tail], 
	Tail = [OldJumpOffset],

	writeln(Offset),

	%	write('Branch: '), writeln((Offset-H)), 

		%		((MN=3, Offset=290) -> spy(get_assoc) ; true),

	b_getval(markedinstr, MKD),
	((get_assoc((MN-Offset), MKD, _VAL)) ->
		((Offset = 354) -> spy(fix_that_there_method) ; true),
		NewH = H,
		fix_that_there_method(MN, TRest, NRest)
	;
		%((Offset = 255) -> trace ; true),
		b_getval(oldtonew, OTN),
		b_getval(newtoold, NTO),

		get_assoc((MN-Offset), NTO, (MN-OldOffset)),
		OldTarget is (OldOffset+4+OldJumpOffset),
		get_assoc((MN-OldTarget), OTN, (MN-NewTarget)),
		NewJumpOffset is (NewTarget-(Offset+4)),

		NewTail = [NewJumpOffset],
		NewH =.. [Head | NewTail],
        
		fix_that_there_method(MN, TRest, NRest)
	).

fix_case_offsets(_, _, _, [], []).
fix_case_offsets(MN, Offset, OldOffset, [CaseOffset|ORest], [NewCaseOffset|NRest]) :-
	b_getval(oldtonew, OTN),
	b_getval(newtoold, NTO),

	OldCaseTarget is (OldOffset+CaseOffset),
	get_assoc((MN-OldCaseTarget), OTN, (MN-NewCaseTarget)),
	NewCaseOffset is (NewCaseTarget-Offset),
	fix_case_offsets(MN, Offset, OldOffset, ORest, NRest).

% Helper function, determines if the instruction is a branching jump instruction
isABranch(ifeq).
isABranch(iffalse).
isABranch(ifge).
isABranch(ifgt).
isABranch(ifle).
isABranch(iflt).
isABranch(ifnge).
isABranch(ifngt).
isABranch(ifnle).
isABranch(ifnlt).
isABranch(ifne).
isABranch(ifstricteq).
isABranch(ifstrictne).
isABranch(iftrue).
isABranch(jump).
isABranch(lookupswitch).

add_sec_var_instructions(MBs, CP, MarkedList, NewMBs, NewMarkedList) :- 

	find_index_multinameCP('navigateToURL', CP, InstrIndex),

	b_setval(instrindices,[InstrIndex]),
	
	find_index_multinameCP('nativeApplication', CP, NativeAppIndex),
	b_setval(nativeappindex,NativeAppIndex),
	find_index_multinameCP('exit', CP, HaltIndex),
	b_setval(haltindex,HaltIndex),
	find_index_multinameCP('isOkay',CP,SecVarIndex),

	format('InstrIndex == ~w~n',[InstrIndex]),

	change_first_method(MBs, CP, SecVarIndex, MarkedList, TempMBs, TempMarkedList),

	insert_guards_overall(TempMBs, InstrIndex, SecVarIndex, HaltIndex, NativeAppIndex, TempMarkedList, NewMBs, NewMarkedList).
	

change_first_method(MBs, _CP, SecVarIndex, MarkedList, NewMBs, NewMarkedList) :-
	reverse(MBs,[R1|RMBs]),
	R1 =.. [method_body, Method, MS, LC, ISD, MSD, CL, C, EC, E, TC, T],
	
	append(First,[O-returnvoid],C),

	instruction_size(findproperty(SecVarIndex),FSVISize),
	instruction_size(initproperty(SecVarIndex),ISVISize),
	
	O1 is O+FSVISize,
	O2 is O1+2,
	O3 is O2+ISVISize,

	Insert = [O - findproperty(SecVarIndex),
		  O1 - pushbyte(0),
		  O2 - initproperty(SecVarIndex),
		  O3 - returnvoid],

	append(First,Insert,C2),
	
	NewCL is CL + FSVISize + 2 + ISVISize,

	R2 =.. [method_body, Method, MS, LC, ISD, MSD, NewCL, C2, EC, E, TC, T],
	TempMBs = [R2|RMBs],
	reverse(TempMBs,NewMBs),

	/* change the marked lists */
	
	reverse(MarkedList,[(Temp1-RM1)|RMarkedList]),

	append(FirstMarked,['Unmarked'],RM1),
	
	append(FirstMarked,
		['Marked',
		 'Marked',
		 'Marked',
	         'Unmarked'],ChangedRM1),

	reverse([(Temp1-ChangedRM1)|RMarkedList],NewMarkedList).

%----------------------------------------------------------

%Search through each method body to see if it has the security 
%relevant instruction given by the method name residing at 
%MultinameIndex. Insert guards around that instruction.
%For right now, assuming that the sec rel event is going to be a 
%method call, of the form callpropvoid(index, arg_count). 
%TODO: change insert_instr_method_body to handle other method
%calls such as callproplex(index, arg_count), or callstatic(i, a).
%
%
%TODO: Not sure if setlocal_1 and getlocal_1 are okay to use 
%here. Could there be other values stored in those registers?
%How do we know whether they're free to use?
%
%InstrINdex is the multiname CP index of the security relevant instruction.
%SecVarIndex is the multiname CP index of the security variable.
%HaltIndex is the multiname CP index of the halt method.

insert_guards_overall([], _InstrIndex, _SecVarIndex, _HaltIndex, _NativeAppIndex, MarkedList, [], MarkedList).

insert_guards_overall([MB|MBs], InstrIndex, SecVarIndex, HaltIndex, NativeAppIndex, [(Method-MarkedC)|MarkedCs], 
					[NewMB|NewMBs], [(Method-NewMarkedC)|NewMarkedCs]) :- 

	MB =..  [method_body, Method, MS, LC, ISD,
       		MSD, CL, C, EC, E, TC, T],
	
	instruction_size(findproperty(NativeAppIndex),S1),
	instruction_size(callpropvoid(HaltIndex,0),S2),
	Sum is S1 + S2,

	modify_method_body(C, NewC, MarkedC, NewMarkedC, 0, NewCL, LC, Method, 0, [InstrIndex], [
							(0-findproperty(SecVarIndex),'Marked'), 
							(0-getproperty(SecVarIndex),'Marked'), 
							(0-pushbyte(1),'Marked'),
							(0-add,'Marked'),
							(0-setlocal(LC),'Marked'),
							(0-findproperty(SecVarIndex),'Marked'),
							(0-getlocal(LC),'Marked'),
							(0-setproperty(SecVarIndex),'Marked'),
							(0-pop,'Marked'),
							(0-pop,'Marked'),
							(0-findproperty(SecVarIndex),'Marked'),
							(0-getproperty(SecVarIndex),'Marked'),
							(0-pushbyte(3),'Marked'),
							(0-iflt(Sum),'Marked'),
							(0-findproperty(NativeAppIndex),'Marked'),
							(0-callpropvoid(HaltIndex, 0),'Unmarked')
						]),
/*
	insert_instr_method_body(Method, 0, C, CL, InstrIndex, [
							findproperty(SecVarIndex), 
							getproperty(SecVarIndex), 
							pushbyte(1),
							add,
							setlocal(LC),
							findproperty(SecVarIndex),
							getlocal(LC),
							setproperty(SecVarIndex),
							pop,
							pop,
							findproperty(SecVarIndex),
							getproperty(SecVarIndex),
							pushbyte(3),
							iflt(Sum),
							findproperty(NativeAppIndex),
							callpropvoid(HaltIndex, 0)
						], NewC, 0, NewCL, 0, MarkedC, NewMarkedC), 
*/
	NewLC is LC + 1,
	NewMS is MS + 2,

	NewMB =.. [method_body, Method, NewMS, NewLC, ISD,
       		MSD, NewCL, NewC, EC, E, TC, T],


		
	insert_guards_overall(MBs, InstrIndex, SecVarIndex, HaltIndex, NativeAppIndex, MarkedCs, NewMBs, NewMarkedCs).

add_marked_branch(MethodNum, Offset, iflt(_)) :-
	!,
	b_getval(markedinstr,MKD1),
	put_assoc((MethodNum-Offset), MKD1, 1, MKD2),
	b_setval(markedinstr,MKD2).

add_marked_branch(_, _Offset, _I).


create_initial_lists(_, NewOffset, NewOffset, [], [], []).

create_initial_lists(MethodNum, Offset, NewOffset, [(_Off-I,Mark)|Is], [Offset-I|NewIs], [Mark|Marks]) :-
	
	% Add branches to the marked branch association list
	add_marked_branch(MethodNum, Offset, I),

	instruction_size(I, CLInstr),
	CurOffset is (Offset+CLInstr),

	create_initial_lists(MethodNum, CurOffset, NewOffset, Is, NewIs, Marks).


modify_method_body([], [], [], [], CL, CL, _, _MethodNum, _CurrentOffset, _MultinameIndexes, _InsertList).

modify_method_body([Offset - I | Rest], NewInsList, [MarkIns | MarkedInsList], NewMarkedList, 
		   CL, NewCL, LC, MethodNum, CurrentOffset, [MultinameIndex], InsertList) :-

			   %((MethodNum = 18) -> spy(create_insert_list) ; true),

	% Check if it's the correct instruction and args.				
	I =.. [Head1, Head2|_Tail],
	Head1 = callpropvoid,
	Head2 = MultinameIndex,

	create_initial_lists(MethodNum, CurrentOffset, TempOffset, InsertList, TempInsertList, TempMarkedList),
	append(TempMarkedList, ['Unmarked'], FullMarkList),
	append(TempInsertList, [(TempOffset-I)], FullInsertList),

	instruction_size(I, CLInstr),

	NextOffset is TempOffset+CLInstr,

	% Add the offsets to the new assoc list
	b_getval(oldtonew,OTN),
	b_getval(newtoold,NTO),

	put_assoc((MethodNum-Offset), OTN, (MethodNum-CurrentOffset), OTN2),
	put_assoc((MethodNum-CurrentOffset), NTO, (MethodNum-Offset), NTO2),

	b_setval(oldtonew,OTN2),
	b_setval(newtoold,NTO2),

	SumSize is (NextOffset-CurrentOffset),

	% Increment the instruction count
	TempCL is (CL+SumSize),

	% Find out the length of the old Instr	
	NewCurOffset is (CurrentOffset + SumSize),

	% Recursively call
	modify_method_body(Rest, NewRest, MarkedInsList, NewMarkedInsList, TempCL, NewCL, LC, 
			   MethodNum, NewCurOffset, MultinameIndexes, InsertList),

	append(FullMarkList, NewMarkedInsList, NewMarkedList),
	append(FullInsertList, NewRest, NewInsList).

modify_method_body([Offset - I | Rest], [CurrentOffset - I | NewRest], 
		   [Marking | MarkList], [NewMarking | NewMarkList], 
		   CL, NewCL, LC, MethodNum, CurrentOffset, MultinameIndexes, InsertList) :-

	% Add the offsets to the new assoc list
	b_getval(oldtonew,OTN),
	b_getval(newtoold,NTO),

	put_assoc((MethodNum-Offset), OTN, (MethodNum-CurrentOffset), OTN2),
	put_assoc((MethodNum-CurrentOffset), NTO, (MethodNum-Offset), NTO2),

	b_setval(oldtonew,OTN2),
	b_setval(newtoold,NTO2),

	% For this policy, all original instructions are left unmarked
	NewMarking = Marking, 

	% Find out the length of the old Instr	
	instruction_size(I, CLInstr),
	NextCurOffset is (CurrentOffset + CLInstr),

	% Add 1 to the instruction count
	TempCL is (CL+CLInstr),

	% Recursively call
	modify_method_body(Rest, NewRest, MarkList, NewMarkList, TempCL, NewCL, LC, 
			   MethodNum, NextCurOffset, MultinameIndexes, InsertList). 

%-----------------------------------------------
insert_instr_method_body(MethodNum, CurOffset, [Offset - I|Rest], CL, MultinameIndex, InstrsToInsert,
			   	NewC, OldAddOffset, NewCL, 0,
			       	[_MarkedCodePoint|MarkedCodePoints], 
				NewMarkedCodePoints) :-
	% Check if it's the correct instruction and args.				
	I =.. [Head1, Head2|_Tail],
	Head1 = callpropvoid,
	Head2 = MultinameIndex,

	%	format('I is ~w~n~n', [I]),
	%	spy(create_oi_array),
	% Create the new front part of Instr Array
	create_oi_array(MethodNum, CurOffset, InstrsToInsert, Offset, Front, 0, SumSize, NewInstrMarks),

	%	writeln(InstrsToInsert), 
	%	writeln('---------'),
	%	writeln(NewInstrMarks),

	% Manipulate the offsets correctly.
	NewAddOffset is OldAddOffset + SumSize,

	%Set everything in the jump table 
	b_getval(jumptable, JumpTable),
	get_method_jumplist(JumpTable,MethodNum,MethodJumpList),

%	format('In IIMB, SumSize = ~w~n~n~n',[SumSize]),
	b_setval(securitysize,SumSize),
	set_method_jumplist(JumpTable,MethodNum,[(Offset,SumSize)|MethodJumpList],NewJumpTable),
%	format('MJL = ~w, NewJumpTable = ~w~n~n', [MethodJumpList,NewJumpTable]),
	b_setval(jumptable, NewJumpTable),

	% Find out the length of the old Instr	
	instruction_size(I, CLInstr),
	RestCL is CL - CLInstr,
%	%---------------- debugging
%	writeln('case 1 of IIMB ----------------------------------------->'),
%	format('Array = ~w~n~n InstrsToInstr = ~w~n~n', [[Offset - I|Rest],InstrsToInsert]),
	%---------------------------

	NextCurOffset is (CurOffset + CLInstr + SumSize),

	% Recursively call
	insert_instr_method_body(MethodNum, NextCurOffset, Rest, RestCL, MultinameIndex, InstrsToInsert, NewRest, NewAddOffset, NewRestCL, 0, MarkedCodePoints, TempMarkedCodePoints),

	%----------------------------------------------------------------------
	% Pass up the correct NewC
	NewOffset is Offset + SumSize + OldAddOffset,
	%NewOffset is Offset + SumSize,
	Front = [FrontO - FrontI| FrontRest],
	NewFrontO is FrontO + OldAddOffset,


	reset_offsets(NewFrontO,[FrontO - FrontI|FrontRest],ResetList),


%	append([NewFrontO - FrontI|FrontRest], [NewOffset - I], NewFront),
	append(ResetList,[NewOffset-I],NewFront),
	append(NewFront, NewRest, NewC),

	% Add the offsets to the new assoc list
	b_getval(oldtonew,OTN),
	b_getval(newtoold,NTO),

	put_assoc((MethodNum-Offset), OTN, (MethodNum-NewOffset), OTN2),
	put_assoc((MethodNum-NewOffset), NTO, (MethodNum-Offset), NTO2),

	b_setval(oldtonew,OTN2),
	b_setval(newtoold,NTO2),



%	format('NewC is ~w~n~n',[NewC]),
%	format('NewOffset is ~w, Offset=~w, SumSize=~w, OldAddOffset=~w~n~n',[NewOffset,Offset,SumSize,OldAddOffset]),
%	format('Offset = ~w, NewFrontO=~w, Fronto=~w, OldAddOffset=~w~n~n', [Offset, NewFrontO, FrontO, OldAddOffset]),

	%=============================== Marked Lists ======================================

	NewInstrMarks = [(FrontO - FrontI, 'Marked')|MarkedRest],

	append([(NewFrontO - FrontI,'Marked')|MarkedRest],[(NewOffset - I,'Unmarked')],UpdatedInstrMarks),
	% append the correct Marked lists


	instruction_size(I,ISize),
	FirstMarkedOffset is NewOffset + ISize,
	reset_offsets_in_marked_lists(MethodNum, FirstMarkedOffset,TempMarkedCodePoints,ResetMarkedCodePoints), 
	append(UpdatedInstrMarks, ResetMarkedCodePoints, NewMarkedCodePoints1), 

	%	format('NewMarked = ~w~n~n',[NewMarkedCodePoints1]),
	%	format('after---------------------------------------------------------'),
	
		correct_halt_instr(NewMarkedCodePoints1,NewMarkedCodePoints),

	%	NewMarkedCodePoints = NewMarkedCodePoints1,
	%======================================================================================
	%format('NewMarkedCodePoints are ~w~n',[NewMarkedCodePoints]),

	% Pass up the correct CL
	NewCL is NewRestCL + CLInstr + SumSize.

insert_instr_method_body(MethodNum, CurOffset, [Offset - I|Rest], CL, MultinameIndex, InstrsToInsert,
				[NewOffset - I|NewRest], OldAddOffset, NewCL, Flag,
				[MarkedCodePoint|MarkedCodePoints], 
				[NewMarkedCodePoint|NewMarkedCodePoints]) :-
		% Check if it's the correct instruction and args.
		%writeln(Offset - I),		
	I =.. [Head1, Head2|_Tail],
	Head1 = callpropvoid,
	Head2 \= MultinameIndex,

	%format('I is ~w~n~n', [I]),
	% Manipulate the offsets correctly.
	NewOffset is Offset + OldAddOffset,
	NewAddOffset is OldAddOffset,

	% Add the offsets to the new assoc list
	b_getval(oldtonew,OTN),
	b_getval(newtoold,NTO),

	put_assoc((MethodNum-Offset), OTN, (MethodNum-NewOffset), OTN2),
	put_assoc((MethodNum-NewOffset), NTO, (MethodNum-Offset), NTO2),

	b_setval(oldtonew,OTN2),
	b_setval(newtoold,NTO2),

	% Find out the length of the Instr
	instruction_size(I, CLInstr),
	%	format('in IIMB, I=~w, CLInstr=~w~n',[I,CLInstr]),

	RestCL is CL - CLInstr,

	NextCurOffset is CurOffset + CLInstr,
		
	% Recursively call
	insert_instr_method_body(MethodNum, NextCurOffset, Rest, RestCL, MultinameIndex, InstrsToInsert, NewRest, 
	                         NewAddOffset, NewRestCL, Flag,
				 MarkedCodePoints, NewMarkedCodePoints),

	NewMarkedCodePoint = MarkedCodePoint,
	% Pass up the correct CL
	NewCL is NewRestCL + CLInstr.

insert_instr_method_body(MethodNum, CurOffset, [Offset - I|Rest], CL, MultinameIndex, InstrsToInsert,
				[NewOffset - I|NewRest], OldAddOffset, NewCL, Flag,
				[MarkedCodePoint|MarkedCodePoints], 
				[NewMarkedCodePoint|NewMarkedCodePoints]) :-			

	I =.. [Head|_Tail],	
	Head \= callpropvoid,	

	%format('I is ~w~n~n', [I]),
	% Manipulate the offsets correctly.
	NewOffset is Offset + OldAddOffset,
	NewAddOffset is OldAddOffset,

	% Add the offsets to the new assoc list
	b_getval(oldtonew,OTN),
	b_getval(newtoold,NTO),

	put_assoc((MethodNum-Offset), OTN, (MethodNum-NewOffset), OTN2),
	put_assoc((MethodNum-NewOffset), NTO, (MethodNum-Offset), NTO2),

	b_setval(oldtonew,OTN2),
	b_setval(newtoold,NTO2),

	% Find out the length of the Instr
	instruction_size(I, CLInstr),

	NextCurOffset is CurOffset + CLInstr,

	RestCL is CL - CLInstr,
		
	% Recursively call
	insert_instr_method_body(MethodNum, NextCurOffset, Rest, RestCL, MultinameIndex, InstrsToInsert, NewRest,
       	                       	 NewAddOffset, NewRestCL, Flag,
			 	 MarkedCodePoints, NewMarkedCodePoints),
	
	NewMarkedCodePoint = MarkedCodePoint,
	% Pass up the correct CL
	%
	NewCL is NewRestCL + CLInstr.

insert_instr_method_body(_MethodNum, _, [], CL, _MultinameIndex, _InstrsToInsert, [], _AddOffset, CL, _,
MarkedCodePoints, MarkedCodePoints).
	%writeln('case 5').

%-----------------------------------------------------------
create_oi_array(MethodNum, CurOffset, [Instr|InstrArray], InitOffset, [InitOffset - Instr|OIArray],
		 OldSumSize, NewSumSize,
	 	 [MarkedCodePoint|MarkedCodePoints]) :-

	% Add the offsets to the marked instruction list
	b_getval(markedinstr,MKD),
	TempHolder is (CurOffset + OldSumSize),
	%	write('Inserted: '), writeln((MethodNum-TempHolder)),
	put_assoc((MethodNum-TempHolder), MKD, 1, MKD2),
	b_setval(markedinstr,MKD2),

	instruction_size(Instr, InstrSize),
	NextOffset is InitOffset + InstrSize,
	NextSumSize is OldSumSize + InstrSize,
	MarkedCodePoint = (InitOffset - Instr, 'Marked'),
	create_oi_array(MethodNum, CurOffset, InstrArray, NextOffset, OIArray, NextSumSize, NewSumSize,
			MarkedCodePoints).
create_oi_array(_, _, [], _OffsetToAdd, [], SumSize, SumSize, []).

reset_offsets(FirstOffset,[_O-I|Rest],ResetList) :-
	instruction_size(I,Size),
	NextOffset is FirstOffset + Size,
	reset_offsets(NextOffset,Rest,NewRest),
	ResetList = [FirstOffset - I|NewRest].
reset_offsets(_FirstOffset,[],[]).

reset_offsets_in_marked_lists(MethodNum, FirstOffset,[(_O2-I2,Marking)|Rest],NewMarkedCodePoints) :-

	

	instruction_size(I2,I2Size),
	NextOffset is FirstOffset + I2Size, 
	reset_offsets_in_marked_lists(MethodNum, NextOffset,Rest,NewRest),
	NewMarkedCodePoints = [(FirstOffset-I2,Marking)|NewRest].
reset_offsets_in_marked_lists(_MethodNum, _FirstOffset,[],[]).
	
get_method_jumplist([(CurrMethodNum,_CurrJumpList)|JumpTable],MethodNum,JumpList) :-
	CurrMethodNum \= MethodNum,
	get_method_jumplist(JumpTable,MethodNum,JumpList).
get_method_jumplist([(MethodNum,JumpList)|_JumpTable],MethodNum,JumpList).
get_method_jumplist([],MethodNum,[]).
	%	format('method ~ws Jumplist not available',[MethodNum]).

set_method_jumplist([(CurrMethodNum,CurrJumpList)|JumpTable],MethodNum,JumpList,NewJumpTable) :-
	CurrMethodNum \= MethodNum,
	set_method_jumplist(JumpTable,MethodNum,JumpList,TempJumpTable),
	NewJumpTable = [(CurrMethodNum,CurrJumpList)|TempJumpTable].
set_method_jumplist([(MethodNum,_OldJumpList)|JumpTable],MethodNum,NewJumpList,NewJumpTable) :-
	NewJumpTable = [(MethodNum,NewJumpList)|JumpTable].
set_method_jumplist([],MethodNum,JumpList,[(MethodNum,JumpList)]).
	%	format('method ~ws Jumplist not available',[MethodNum]).
	%
is_jump(ifeq).
is_jump(iffalse).
is_jump(ifge).
is_jump(ifgt).
is_jump(ifle).
is_jump(iflt).
is_jump(ifnge).
is_jump(ifngt).
is_jump(ifnle).
is_jump(ifnlt).
is_jump(ifne).
is_jump(ifnge).
is_jump(ifstricteq).
is_jump(ifstrictne).
is_jump(iftrue).
is_jump(jump).

correct_halt_instr([First|Rest],[NewFirst|NewRest]) :-
	b_getval(nativeappindex,NAI),
	b_getval(haltindex,HI),
	%format('NAI = ~w, HI = ~w~n',[NAI,HI]),
	First = (O - callpropvoid(HI,ArgCount),_Marking),
       	NewMarking = 'Unmarked',
	NewFirst = (O - callpropvoid(HI,ArgCount),NewMarking),
	correct_halt_instr(Rest,NewRest).
correct_halt_instr([First|Rest],[NewFirst|NewRest]) :-
	b_getval(nativeappindex,NAI),
	b_getval(haltindex,HI),
	%format('NAI = ~w, HI = ~w~n',[NAI,HI]),
	First \= (O - callpropvoid(HI,ArgCount),_Marking),
        NewFirst = First,
	correct_halt_instr(Rest,NewRest).
correct_halt_instr([],[]).
